package com.zzh.lib.views.indicators;


import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Build;
import android.util.AttributeSet;

import com.zzh.lib.views.banner.BaseIndicatorView;

import androidx.annotation.DrawableRes;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;

/**
 * Created by ZZH on 2023/2/16.
 *
 * @date: 2023/2/16 15:21
 * @email: zzh_hz@126.com
 * @author: zzh
 * @description: com.zzh.lib.views.indicators
 */
public class DrawableIndicator extends BaseIndicatorView {
    // 选中时的Bitmap
    private Bitmap mCheckedBitmap = null;

    // 未选中时的Bitmap
    private Bitmap mNormalBitmap;

    // 图片之间的间距
    private int mIndicatorPadding = 0;

    // 选中图片的宽度
    private int mCheckedBitmapWidth = 0;

    // 选中图片的高度
    private int mCheckedBitmapHeight = 0;

    //未选中图片的宽高
    private int mNormalBitmapWidth = 0;
    private int mNormalBitmapHeight = 0;
    private IndicatorSize mIndicatorSize = null;
    private boolean normalCanResize = true;
    private boolean checkCanResize = true;

    public DrawableIndicator(Context context) {
        super(context);
    }

    public DrawableIndicator(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawableIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public DrawableIndicator(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int maxHeight = mCheckedBitmapHeight;
        if (mCheckedBitmapHeight < mNormalBitmapHeight) {
            mCheckedBitmapHeight = mNormalBitmapHeight;
        }
        int realWidth =
                mCheckedBitmapWidth + (mNormalBitmapWidth + mIndicatorPadding) * (getPageSize() - 1);
        setMeasuredDimension(realWidth, maxHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getPageSize() > 1 && mCheckedBitmap != null && mNormalBitmap != null) {
            for (int i = 1; i < getPageSize() + 1; i++) {
                int left, top;
                var bitmap = mNormalBitmap;
                int index = i - 1;

                if (index < getCurrentPosition()) {
                    left = (i - 1) * (mNormalBitmapWidth + mIndicatorPadding);
                    top = getMeasuredHeight() / 2 - mNormalBitmapHeight / 2;
                } else if (index == getCurrentPosition()) {
                    left = (i - 1) * (mNormalBitmapWidth + mIndicatorPadding);
                    top = getMeasuredHeight() / 2 - mCheckedBitmapHeight / 2;
                    bitmap = mCheckedBitmap;
                } else {
                    left = (i - 1) * mIndicatorPadding + (i - 2) * mNormalBitmapWidth + mCheckedBitmapWidth;
                    top = getMeasuredHeight() / 2 - mNormalBitmapHeight / 2;
                }
                drawIcon(canvas, left, top, bitmap);
            }
        }
    }

    private void drawIcon(
            Canvas canvas,
            int left,
            int top,
            Bitmap icon
    ) {
        if (icon == null) {
            return;
        }
        canvas.drawBitmap(icon, left, top, null);
    }

    private void initIconSize() {
        if (mCheckedBitmap != null) {
            if (mIndicatorSize != null) {

                if (mCheckedBitmap.isMutable() && checkCanResize) {
                    mCheckedBitmap.setWidth(mIndicatorSize.checkedWidth);
                    mCheckedBitmap.setHeight(mIndicatorSize.checkedHeight);
                } else {
                    int width = mCheckedBitmap.getWidth();
                    int height = mCheckedBitmap.getHeight();
                    float scaleWidth = mIndicatorSize.checkedWidth / width;
                    float scaleHeight = mIndicatorSize.checkedHeight / height;
                    Matrix matrix = new Matrix();
                    matrix.postScale(scaleWidth, scaleHeight);
                    mCheckedBitmap = Bitmap.createBitmap(mCheckedBitmap, 0, 0, width, height, matrix, true);
                }


            }
            mCheckedBitmapWidth = mCheckedBitmap.getWidth();
            mCheckedBitmapHeight = mCheckedBitmap.getHeight();
        }

        if (mNormalBitmap != null) {
            if (mIndicatorSize != null) {
                if (mNormalBitmap.isMutable() && normalCanResize) {
                    mNormalBitmap.setWidth(mIndicatorSize.normalWidth);
                    mNormalBitmap.setHeight(mIndicatorSize.normalHeight);
                } else {
                    int width = mNormalBitmap.getWidth();
                    int height = mNormalBitmap.getHeight();
                    float scaleWidth = mIndicatorSize.normalWidth / mNormalBitmap.getWidth();
                    float scaleHeight = mIndicatorSize.normalHeight / mNormalBitmap.getHeight();
                    Matrix matrix = new Matrix();
                    matrix.postScale(scaleWidth, scaleHeight);
                    mNormalBitmap = Bitmap.createBitmap(mNormalBitmap, 0, 0, width, height, matrix, true);
                }
            }
            mNormalBitmapWidth = mNormalBitmap.getWidth();
            mNormalBitmapHeight = mNormalBitmap.getHeight();
        }
    }

    public DrawableIndicator setIndicatorDrawable(@DrawableRes int normalDrawable, @DrawableRes int checkedDrawable) {
        mNormalBitmap = BitmapFactory.decodeResource(getResources(), normalDrawable);
        mCheckedBitmap = BitmapFactory.decodeResource(getResources(), checkedDrawable);
        if (mNormalBitmap == null) {
            mNormalBitmap = getBitmapFromVectorDrawable(context, normalDrawable);
            normalCanResize = false;
        }
        if (mCheckedBitmap == null) {
            mCheckedBitmap = getBitmapFromVectorDrawable(context, checkedDrawable);
            checkCanResize = false;
        }
        initIconSize();
        postInvalidate();
        return this;
    }

    public DrawableIndicator setIndicatorSize(
            int normalWidth,
            int normalHeight,
            int checkedWidth,
            int checkedHeight
    ) {
        mIndicatorSize = new IndicatorSize(normalWidth, normalHeight, checkedWidth, checkedHeight);
        initIconSize();
        postInvalidate();
        return this;
    }

    public DrawableIndicator setIndicatorGap(int padding) {
        if (padding >= 0) {
            mIndicatorPadding = padding;
            postInvalidate();
        }
        return this;
    }

    private Bitmap getBitmapFromVectorDrawable(
            Context context,
            int drawableId
    ){
        var drawable = ContextCompat.getDrawable(context, drawableId);
        if (drawable != null){
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
                drawable = DrawableCompat.wrap(drawable).mutate();
            }
            Bitmap bitmap = Bitmap.createBitmap(
                    drawable.getIntrinsicWidth(),
                    drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas =new Canvas(bitmap);
            drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
            drawable.draw(canvas);
            return bitmap;
        }

        return null;
    }

    static class IndicatorSize {
        public int normalWidth;
        public int normalHeight;
        public int checkedWidth;
        public int checkedHeight;

        public IndicatorSize(int normalWidth, int normalHeight, int checkedWidth, int checkedHeight) {
            this.normalWidth = normalWidth;
            this.normalHeight = normalHeight;
            this.checkedWidth = checkedWidth;
            this.checkedHeight = checkedHeight;
        }
    }
}
